package org.phonetic.aspect;

import java.util.List;

import javax.persistence.EntityManager;

import org.application.bean.PacienteDao;
import org.application.model.Paciente;

import br.com.p2d.phonetizer.FonetizacaoBR;

/**
 * Aspeto para realizar a busca fonética do atributo Nome da classe Paciente
 */
public aspect PhoneticSearch {

	/**
	 * cria um alerta no método de busca na classe DAO informando a existencia
	 * do aspecto
	 */
	declare warning : execution( List<Paciente> PacienteDao.getByNome(..)) : "A implementação deste método foi substituida pelo aspecto org.phonetic.aspect.PhoneticSearch";

	/**
	 * Ponto de corte
	 * 
	 * @param name
	 *            - String que será fonetizada (String)
	 * @param dao
	 *            - Classe alvo do aspecto que contém instância do entityManager
	 *            (org.application.bean.PacienteDao)
	 */
	pointcut executeNewSearch(String name, PacienteDao dao) 
	: execution( List<Paciente> PacienteDao.getByNome(String)) && args(name) && target(dao);

	/**
	 * User Advice
	 * 
	 * @param name
	 *            - String
	 * @param dao
	 *            - org.application.bean.PacienteDao
	 * @return List<User>
	 */
	List<Paciente> around(String name, PacienteDao dao) : executeNewSearch(name, dao){
		return execute(name, dao);
	}

	/**
	 * Fonetiza a string passada no parametro e busca na base de dados
	 * 
	 * @param name
	 *            - String
	 * @param dao
	 *            - org.application.bean.PacienteDao
	 * @return List<User>
	 */
	@SuppressWarnings("unchecked")
	private List<Paciente> execute(String name, PacienteDao dao) {
		EntityManager entityManager = dao.getEntityManager();
		String hash = FonetizacaoBR.makePhoneticCode(name);
		String query = "SELECT distinct (p) FROM Paciente p, PacientePhoneticCode ppc, PhoneticCode pc WHERE pc.hash = :hash " +
				"AND ppc.phoneticCode.id = pc.id AND ppc.paciente.id = p.id";
		return entityManager.createQuery(query).setParameter("hash", hash)
				.getResultList();
	}
}